<?xml version="1.0" ?>

<xsl:stylesheet   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
						xmlns:lzc="http://schemas.icitadel.com/Lazarus/Compiled.xsd"
                  version="1.0">

   <xsl:output method="text"/>

	<xsl:include href="../../common.xsl" />
	<xsl:include href="../../convert.xsl" />
   
   <xsl:template match="lzc:project"><xsl:apply-templates select="lzc:objects/lzc:object[ ( @compiling ) ]" /></xsl:template>

   <xsl:template match="lzc:object[ @compiling ]">
			<xsl:variable name="v_ObjectName">
				<xsl:value-of select="@name" />
			</xsl:variable>
			<xsl:variable name="v_ObjectLogicalName">
				<xsl:value-of select="@logical-name" />
			</xsl:variable>
         <xsl:variable name="v_DetailName">
            <xsl:value-of select="@name" /><xsl:text>Detail</xsl:text>
         </xsl:variable>
         <xsl:variable name="v_CollectionName"><xsl:value-of select="@name" /><xsl:text>Collection</xsl:text>
         </xsl:variable>
         <xsl:variable name="v_collections" select="lzc:collections/lzc:collection" />
         <xsl:variable name="v_NamespacePrefix">
				<xsl:if test="/lzc:project/@namespaceprefix">
					<xsl:value-of select="/lzc:project/@namespaceprefix" />
					<xsl:text>:</xsl:text>
				</xsl:if>
         </xsl:variable>
         <xsl:variable name="v_RuntimeNamespace">
				<xsl:if test="ancestor::lzc:project/@defaultnamespace">
					<xsl:value-of select="ancestor::lzc:project/@defaultnamespace"/>
				</xsl:if>
         </xsl:variable>
         <xsl:variable name="v_BusinessConceptNamespace">
				<xsl:if test="/lzc:project/@businessconcept">
					<xsl:text>.</xsl:text>
					<xsl:value-of select="/lzc:project/@businessconcept" />
				</xsl:if>
         </xsl:variable>
<xsl:text>using System;
using System.Data;
using System.Xml;

using OR.Reuse.Persistence;

using Derived = </xsl:text>
	<xsl:value-of select="$v_RuntimeNamespace" />
	<xsl:value-of select="$v_BusinessConceptNamespace" />
	<xsl:text>;

</xsl:text>

<xsl:text>namespace </xsl:text>
	<xsl:value-of select="$v_RuntimeNamespace" />
	<xsl:value-of select="$v_BusinessConceptNamespace" />
	<xsl:text>.Generated
{
	/// &lt;summary&gt;
	/// </xsl:text><xsl:value-of select="lzc:description" /><xsl:text>
	/// &lt;/summary&gt;
   public class </xsl:text><xsl:value-of select="$v_DetailName" /> : EntityBase
   {<xsl:for-each select="lzc:fields/lzc:field[ not( .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ) ]"><xsl:text>
		protected </xsl:text>
				<xsl:call-template name="getNETParamType">
					<xsl:with-param name="pFieldType" select="@type" />
					<xsl:with-param name="pRequired" select="@required" />
				</xsl:call-template>
				<xsl:text> m</xsl:text>
				<xsl:value-of select="@name" />
			<xsl:text>;</xsl:text>
	</xsl:for-each>

<xsl:if test="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
	<xsl:text>
	</xsl:text>
</xsl:if>
	
	<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]"><xsl:text>
		protected Derived.</xsl:text>
			<xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@object" /><xsl:text>Detail</xsl:text>
			<xsl:text> m</xsl:text>
			<xsl:value-of select="@name" />
			<xsl:text>;</xsl:text>
	</xsl:for-each>

<xsl:if test="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
	<xsl:text>
	</xsl:text>
</xsl:if>
	
	<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]"><xsl:text>
		protected Derived.</xsl:text><xsl:value-of select="@object" />Collection m<xsl:value-of select="@name" /><xsl:text>;</xsl:text>
	</xsl:for-each>

<xsl:text>
</xsl:text>

	<xsl:text>
		public </xsl:text><xsl:value-of select="$v_DetailName" /><xsl:text>()
		{</xsl:text>
		<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
			<xsl:text>
			m</xsl:text>
			<xsl:value-of select="@name" />
			<xsl:text> = new Derived.</xsl:text>
			<xsl:value-of select="@object" />
			<xsl:text>Collection();
			m</xsl:text>
			<xsl:value-of select="@name" />
			<xsl:text>.ParentEntity = this;</xsl:text>
	</xsl:for-each>
	<xsl:text>
	</xsl:text>
		<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]"><xsl:text>
			m</xsl:text>
			<xsl:value-of select="@name" />
			<xsl:text> = new Derived.</xsl:text>
			<xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@object" /><xsl:text>Detail();
			m</xsl:text>
			<xsl:value-of select="@name" />
			<xsl:text>.ParentEntity = this;</xsl:text>
	</xsl:for-each>
<xsl:text>
		}
	</xsl:text>
	<xsl:for-each select="lzc:fields/lzc:field">
	<xsl:text>
		/// </xsl:text>&lt;summary&gt;<xsl:text>
		/// </xsl:text>
				<xsl:value-of select="lzc:description" />
			 <xsl:text>
		/// </xsl:text>&lt;/summary&gt;<xsl:text>
		public </xsl:text>
			<xsl:choose>
			<xsl:when test="not( .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] )">
				<xsl:call-template name="getNETParamType">
					<xsl:with-param name="pFieldType" select="@type" />
					<xsl:with-param name="pRequired" select="@required" />
				</xsl:call-template>
				<xsl:value-of select="$space" />
				<xsl:value-of select="@logical-name" />
<xsl:text>
		{
			get
			{
				return ( m</xsl:text><xsl:value-of select="@name" /> );
			}
			set
			{
				m<xsl:value-of select="@name" /><xsl:text> = value;
			}
		}
</xsl:text>
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="v_szFieldType">
					<xsl:text>Derived.</xsl:text>
					<xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@object" />
					<xsl:text>Detail</xsl:text>
				</xsl:variable>
				<xsl:variable name="v_szFieldName">
					<xsl:value-of select="@name" />
				</xsl:variable>
				<xsl:value-of select="$v_szFieldType" />
				<xsl:value-of select="$space" />
				<xsl:value-of select="$v_szFieldName" />
<xsl:text>
		{
			get
			{
				return ( m</xsl:text><xsl:value-of select="$v_szFieldName" /> );
			}
			set
			{
				m<xsl:value-of select="$v_szFieldName" /><xsl:text> = value;
			}
		}
</xsl:text>
			</xsl:otherwise>
			</xsl:choose>
</xsl:for-each>
	<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
	<xsl:text>
		public Derived.</xsl:text><xsl:value-of select="@object" />Collection <xsl:value-of select="@name" /><xsl:text>
		{
			get
			{
				return ( m</xsl:text><xsl:value-of select="@name" /> );
			}
			set
			{
				m<xsl:value-of select="@name" /><xsl:text> = value;
			}
		}
</xsl:text></xsl:for-each>

<xsl:text>
		public override void LoadXml( XmlElement pSource )
		{
			// Scalar Values</xsl:text><xsl:for-each select="lzc:fields/lzc:field[ not( .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ) ]">
				<xsl:choose>
					<xsl:when test="@type = $DATATYPE_TEXT">
						<xsl:text>
			XmlElement v</xsl:text><xsl:value-of select="@name" /><xsl:text> = ( XmlElement )pSource.SelectSingleNode( "</xsl:text><xsl:value-of select="$v_NamespacePrefix" /><xsl:value-of select="@alias" /><xsl:text>", PersistenceConfig.Namespaces );
			
			if ( v</xsl:text><xsl:value-of select="@name" /><xsl:text> != null )
			{
				m</xsl:text><xsl:value-of select="@name" /><xsl:text> = v</xsl:text><xsl:value-of select="@name" /><xsl:text>.InnerText;
			}
			</xsl:text>
					</xsl:when>
					<xsl:otherwise>
						<xsl:text>
			m</xsl:text><xsl:value-of select="@name" /><xsl:text> = </xsl:text>
						<xsl:call-template name="getDataUtilityFunction">
							<xsl:with-param name="pFieldType" select="@type" />
							<xsl:with-param name="pSourceObject">pSource</xsl:with-param>
							<xsl:with-param name="pTargetObject" select="@alias" />
							<xsl:with-param name="pDefault" select="@default" />
							<xsl:with-param name="pRequired" select="@required" />
						</xsl:call-template><xsl:text>;</xsl:text>					
					</xsl:otherwise>
				</xsl:choose>
</xsl:for-each>

<xsl:if test="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
			<xsl:text>

			// FK Values</xsl:text>
</xsl:if>
			<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
				<xsl:variable name="v_szFieldName"><xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@accessor" /></xsl:variable>
				<xsl:variable name="v_szElementName"><xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@alias" /></xsl:variable>
				<xsl:variable name="v_szLocalElement">v<xsl:value-of select="$v_szFieldName" /></xsl:variable>
				
				<xsl:text>
			XmlElement </xsl:text>
				<xsl:value-of select="$v_szLocalElement" />
				<xsl:text> = ( XmlElement )pSource.SelectSingleNode( "</xsl:text>
				<xsl:value-of select="concat( $v_NamespacePrefix, $v_szElementName )" />
				<xsl:text>", PersistenceConfig.Namespaces );</xsl:text>
			<xsl:text>
			
			if ( </xsl:text>
				<xsl:value-of select="$v_szLocalElement" />
				<xsl:text> != null )
			{
				m</xsl:text><xsl:value-of select="@name" />
				<xsl:text>.LoadXml( </xsl:text>
				<xsl:value-of select="$v_szLocalElement" /><xsl:text> );
			}</xsl:text>
			</xsl:for-each>
			
<xsl:if test="collections/collection[ not( @name = $v_ObjectName ) ]">
			<xsl:text>

			// Collections</xsl:text>
</xsl:if>
			<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
				<xsl:variable name="v_szFieldName"><xsl:value-of select="@name" /></xsl:variable>
				<xsl:variable name="v_szLocalElement">v<xsl:value-of select="@name" /></xsl:variable>
				<xsl:text>
			XmlElement </xsl:text>
				<xsl:value-of select="$v_szLocalElement" />
				<xsl:text> = ( XmlElement )pSource.SelectSingleNode( "</xsl:text>
				<xsl:value-of select="concat( $v_NamespacePrefix, @alias )" />
				<xsl:text>", PersistenceConfig.Namespaces );</xsl:text>
			<xsl:text>
			
			if ( </xsl:text>
				<xsl:value-of select="$v_szLocalElement" />
				<xsl:text> != null )
			{
				m</xsl:text><xsl:value-of select="$v_szFieldName" />
				<xsl:text>.LoadXml( </xsl:text>
				<xsl:value-of select="$v_szLocalElement" /><xsl:text> );
			}</xsl:text>
			</xsl:for-each>

<xsl:text>
		}
		
		public override XmlElement SaveXml( XmlDocument p_docContext )
		{
			XmlElement vNewElement	= p_docContext.CreateElement( "</xsl:text><xsl:value-of select="//lzc:project/@namespaceprefix" /><xsl:text>", "</xsl:text><xsl:value-of select="@alias" /><xsl:text>", "</xsl:text><xsl:value-of select="//lzc:project/@namespaceuri" /><xsl:text>" );

			// Scalar Values</xsl:text>
			<xsl:for-each select="lzc:fields/lzc:field[ not( .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ) ]">
				<xsl:variable name="v_szParamType">
					<xsl:call-template name="getNETParamType">
						<xsl:with-param name="pFieldType" select="@type" />
						<xsl:with-param name="pRequired" select="@required" />
					</xsl:call-template>
				</xsl:variable>
				<xsl:variable name="v_szFieldType">
					<xsl:call-template name="getNETType">
						<xsl:with-param name="pFieldType" select="@type" />
					</xsl:call-template>
				</xsl:variable>
				<xsl:choose>
					<xsl:when test="@type = $DATATYPE_VARCHAR"><xsl:text>
			if ( !String.IsNullOrEmpty( m</xsl:text><xsl:value-of select="@name" /><xsl:text> ) )
			{
				vNewElement.SetAttribute( "</xsl:text><xsl:value-of select="@alias" />", m<xsl:value-of select="@name" /><xsl:text> );
			}
					</xsl:text></xsl:when>
					<xsl:when test="@type = $DATATYPE_TEXT"><xsl:text>
			if ( !String.IsNullOrEmpty( m</xsl:text><xsl:value-of select="@name" /><xsl:text> ) )
			{
				XmlElement	v</xsl:text><xsl:value-of select="@name" /><xsl:text> = p_docContext.CreateElement( "</xsl:text><xsl:value-of select="//lzc:project/@namespaceprefix" /><xsl:text>", "</xsl:text><xsl:value-of select="@alias" /><xsl:text>", "</xsl:text><xsl:value-of select="//lzc:project/@namespaceuri" /><xsl:text>" );
				v</xsl:text><xsl:value-of select="@name" /><xsl:text>.InnerText = m</xsl:text><xsl:value-of select="@name" /><xsl:text>;
				vNewElement.AppendChild( v</xsl:text><xsl:value-of select="@name" /><xsl:text> );
			}
					</xsl:text></xsl:when>
					<xsl:when test="$v_szParamType = 'object'"><xsl:text>
			if ( m</xsl:text><xsl:value-of select="@name" /><xsl:text> != null )
			{
				if ( m</xsl:text><xsl:value-of select="@name" /><xsl:text> is </xsl:text><xsl:value-of select="$v_szFieldType" /><xsl:text> )
				{
					vNewElement.SetAttribute( "</xsl:text><xsl:value-of select="@alias" />", m<xsl:value-of select="@name" /><xsl:text>.ToString() );
				}
				else
				{
					throw new ApplicationException( "The value [ " + m</xsl:text><xsl:value-of select="@name" /><xsl:text>.ToString() + " ] of type [ " + m</xsl:text><xsl:value-of select="@name" /><xsl:text>.GetType().ToString() + " ] is invalid.  The field [ </xsl:text><xsl:value-of select="@name" /><xsl:text> ] must be null or type [ </xsl:text><xsl:value-of select="$v_szFieldType" /><xsl:text> ]." );
				}
			}
			</xsl:text></xsl:when>
					<xsl:otherwise><xsl:text>
			vNewElement.SetAttribute( "</xsl:text><xsl:value-of select="@alias" />", m<xsl:value-of select="@name" /><xsl:text>.ToString() );</xsl:text>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
			
			<xsl:if test="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
			<xsl:text>

			// FK Values</xsl:text>
			</xsl:if>
			
			<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
			vNewElement.AppendChild( m<xsl:value-of select="@name" />.SaveXml( p_docContext ) );
			</xsl:for-each>

			<xsl:if test="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
			<xsl:text>

			// Collections
			
			XmlElement	vCollection	= null;</xsl:text>
			</xsl:if>
			
			<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">
			
			vCollection = m<xsl:value-of select="@name" />.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}</xsl:for-each>

			return ( vNewElement );
		}

		public virtual object Clone()
		{
			Derived.<xsl:value-of select="$v_DetailName" /><xsl:text> v_oReturn = new Derived.</xsl:text><xsl:value-of select="$v_DetailName" /><xsl:text>();
			</xsl:text>
			
			<xsl:for-each select="lzc:fields/lzc:field[ not( .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ) ]">
			v_oReturn.<xsl:value-of select="@logical-name" /> = m<xsl:value-of select="@name" /><xsl:text>;</xsl:text>
			</xsl:for-each>

			<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
			v_oReturn.<xsl:value-of select="@name" /> = ( Derived.<xsl:value-of select=".//lzc:index[ @type = $INDEXTYPE_FOREIGN ]/@object" />Detail )m<xsl:value-of select="@name" /><xsl:text>.Clone();</xsl:text>
			</xsl:for-each>
			<xsl:text>
			
			// FK Values</xsl:text>
			
			<xsl:for-each select="lzc:fields/lzc:field[ .//lzc:index[ @type = $INDEXTYPE_FOREIGN ] ]">
			v_oReturn.<xsl:value-of select="@name" /> = this.<xsl:value-of select="@name" />.CloneTyped();
			</xsl:for-each><xsl:text>

			// Collections</xsl:text>
			<xsl:for-each select="lzc:collections/lzc:collection[ not( @name = $v_ObjectName ) ]">

			foreach ( Derived.<xsl:value-of select="@object" />Detail vDetail in m<xsl:value-of select="@name" /> )
			{
				v_oReturn.<xsl:value-of select="@name" />.Add( vDetail.CloneTyped() );
			}</xsl:for-each>
			
			return ( v_oReturn );
		}

		public virtual Derived.<xsl:value-of select="$v_DetailName" /> CloneTyped()
		{
			return ( ( Derived.<xsl:value-of select="$v_DetailName" /> )this.Clone() );
		}
   }
}
   </xsl:template>

</xsl:stylesheet>